package com.easyCode.sqlBuilder.existDb;

import cn.hutool.extra.spring.SpringUtil;
import com.alibaba.druid.sql.ast.statement.SQLColumnDefinition;
import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement;
import com.alibaba.druid.sql.ast.statement.SQLPrimaryKey;
import com.alibaba.druid.sql.ast.statement.SQLTableElement;
import com.alibaba.druid.sql.dialect.mysql.parser.MySqlCreateTableParser;
import com.alibaba.druid.sql.parser.SQLCreateTableParser;
import com.easyCode.sqlBuilder.ConfigureSqlBuilder;
import com.easyCode.sqlBuilder.constants.KeyTypeConstants;
import com.easyCode.sqlBuilder.sqlInfo.BaseDataBaseSqlInfo;
import com.easyCode.sqlBuilder.sqlInfo.BaseFiledSqlInfo;
import com.easyCode.sqlBuilder.sqlInfo.BaseKeySqlInfo;
import com.easyCode.sqlBuilder.sqlInfo.BaseTableSqlInfo;
import com.easyCode.sqlManager.MappingContainer;
import lombok.SneakyThrows;
import org.apache.commons.lang3.StringUtils;
import org.springframework.jdbc.core.JdbcTemplate;

import java.util.List;

/**
 * 从已经存在的数据库导入相关信息,完成模板文件和模拟数据的生成
 *
 * @author 大忽悠
 * @create 2023/1/18 15:55
 */
public class ExistDbSqlBuilder implements ConfigureSqlBuilder {

    private BaseDataBaseSqlInfo baseDataBaseSqlInfo;
    private String[] tableNames;

    public ExistDbSqlBuilder(BaseDataBaseSqlInfo baseDataBaseSqlInfo, String tableNames) {
        this.baseDataBaseSqlInfo = baseDataBaseSqlInfo;
        this.tableNames = tableNames.split(",");
    }

    @Override
    public void setSqlInfo(BaseDataBaseSqlInfo sqlInfo) {
        baseDataBaseSqlInfo = sqlInfo;
    }

    /**
     * @return 返回构建得到的sql语句给SqlExec执行
     */
    @Override
    public String build() {
        autoWireDataBaseInfo();
        return null;
    }

    @SneakyThrows
    private void autoWireDataBaseInfo() {
        JdbcTemplate jdbcTemplate = SpringUtil.getBean(JdbcTemplate.class);
        for (String tableName : tableNames) {
            jdbcTemplate.query("show create table " + tableName, (resultSet) -> {
                //利用Druid提供的工具类来解析创建Table的sql语句
                SQLCreateTableParser sqlCreateTableParser = new MySqlCreateTableParser(resultSet.getString(2));
                SQLCreateTableStatement table = sqlCreateTableParser.parseCreateTable();
                //tableSqlInfo
                BaseTableSqlInfo tableSqlInfo = ((BaseTableSqlInfo) MappingContainer.getSqlInfo(BaseTableSqlInfo.class));
                tableSqlInfo.setTableName(StringUtils.strip(table.getTableName(),"`"));
                tableSqlInfo.setComment(StringUtils.strip(table.getComment().toString(),"'"));
                baseDataBaseSqlInfo.addTableSqlInfo(tableSqlInfo);
                //解析字段信息
                parseFileds(table, tableSqlInfo);
            });
        }
    }

    private void parseFileds(SQLCreateTableStatement table, BaseTableSqlInfo tableSqlInfo) {
        List<SQLTableElement> fieldList = table.getTableElementList();
        int order = 0;
        for (SQLTableElement field : fieldList) {
            if (field instanceof SQLPrimaryKey) {
                SQLPrimaryKey primaryKey = (SQLPrimaryKey) field;
                String primaryKeyName = primaryKey.getColumns().get(0).toString();
                BaseKeySqlInfo keySqlInfo = ((BaseKeySqlInfo) MappingContainer.getSqlInfo(BaseKeySqlInfo.class));
                keySqlInfo.setKeyType(KeyTypeConstants.PRIMARY_KEY);
                keySqlInfo.setColumns(List.of(StringUtils.strip(primaryKeyName,"`")));
                tableSqlInfo.addKey(keySqlInfo);
            } else if (field instanceof SQLColumnDefinition) {
                SQLColumnDefinition columnDefinition = (SQLColumnDefinition) field;
                BaseFiledSqlInfo filedSqlInfo = (BaseFiledSqlInfo) MappingContainer.getSqlInfo(BaseFiledSqlInfo.class);
                filedSqlInfo.setFiledName(StringUtils.strip(columnDefinition.getColumnName(),"`"));
                filedSqlInfo.setFiledType(columnDefinition.getDataType().toString().split("\\(")[0]);
                filedSqlInfo.setAutoIncrement(columnDefinition.isAutoIncrement());
                filedSqlInfo.setComment(StringUtils.strip(columnDefinition.getComment().toString(),"'"));
                filedSqlInfo.setOrder(order++);
                tableSqlInfo.addFiled(filedSqlInfo);
            }
        }
    }

    /**
     * @return 返回构建得到的sqlInfo
     */
    @Override
    public BaseDataBaseSqlInfo getSqlInfo() {
        return baseDataBaseSqlInfo;
    }
}
